package com.clps.rulesregulations.util;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hpsf.NoPropertySetStreamException;
import org.apache.poi.hpsf.PropertySet;
import org.apache.poi.hpsf.PropertySetFactory;
import org.apache.poi.hpsf.SummaryInformation;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.model.PicturesTable;
import org.apache.poi.hwpf.model.StyleDescription;
import org.apache.poi.hwpf.model.StyleSheet;
import org.apache.poi.hwpf.usermodel.CharacterRun;
import org.apache.poi.hwpf.usermodel.Paragraph;
import org.apache.poi.hwpf.usermodel.Picture;
import org.apache.poi.hwpf.usermodel.Range;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.poifs.eventfilesystem.POIFSReaderEvent;
import org.apache.poi.poifs.eventfilesystem.POIFSReaderListener;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTMarkupRange;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @author zhangchao
 * @date 2018-11-28
 */
public class WordUtil {
    //2003
    public static List<String> getWordTitles2003(String path) throws IOException{
        File file = new File(path);
        String filename = file.getName();
        filename = filename.substring(0, filename.lastIndexOf("."));
        InputStream is = new FileInputStream(path);
        HWPFDocument doc = new HWPFDocument(is);
        Range r = doc.getRange();

        List<String> list = new ArrayList<String>();
        for (int i = 0; i < r.numParagraphs(); i++) {
            Paragraph p = r.getParagraph(i);
            // check if style index is greater than total number of styles
            int numStyles =doc.getStyleSheet().numStyles();
            int styleIndex = p.getStyleIndex();
            if (numStyles > styleIndex) {
                StyleSheet style_sheet = doc.getStyleSheet();
                StyleDescription style = style_sheet.getStyleDescription(styleIndex);
                String styleName = style.getName();
//                System.out.println(styleName);
                if (styleName!=null&&styleName.contains("标题")) {
                    String text = p.text();
                    list.add(text);
                }
            }
        }

        //TODO 图表跟图片不一样，需另外处理
        //得到word数据流
        byte [] dataStream = doc.getDataStream();
        //用于在一段范围内获得段落数
        int numCharacterRuns = r.numCharacterRuns();
//        System.out.println("CharacterRuns 数:"+numCharacterRuns);
        //负责图像提取  和    确定一些文件某块是否包含嵌入的图像。
        PicturesTable table = new PicturesTable(doc, dataStream, null, null, null);

        //文章图片编号
        int i = 1;
        for(int j=0 ; j<numCharacterRuns ; j++){
            //这个类表示一个文本运行，有着共同的属性。
            CharacterRun run = r.getCharacterRun(j);
            //是否存在图片
            boolean bool = table.hasPicture(run);
            if(bool){
                //返回图片对象绑定到指定的CharacterRun
                Picture pic = table.extractPicture(run, true);
                //图片的内容字节写入到指定的输出流。
                pic.writeImageContent(new FileOutputStream("E:\\temp\\"+filename+"_"+i+".jpg"));
                i++;
            }
        }
        return list;
    }

    public static List<String> getWordTitles2007(String path) throws IOException{

        InputStream is = new FileInputStream(path);

        //2007
        List<String> list = new ArrayList<String>();
        XWPFDocument doc = new XWPFDocument(is);
        List<XWPFParagraph> paras = doc.getParagraphs();
//        for (XWPFParagraph xwpfParagraph : doc.getParagraphs()) {
//            CTP ctp = xwpfParagraph.getCTP();
//            CTR[] runs = ctp.getRArray();
//            CTMarkupRange[] commentRangeStarts = ctp.getCommentRangeStartArray();
//            CTMarkupRange[] commentRangeEnds = ctp.getCommentRangeEndArray();
//        }
        for (XWPFParagraph graph : paras) {
            String text = graph.getParagraphText();
            List<CTMarkupRange> bookmarkEndList = graph.getCTP().getBookmarkEndList();
            System.out.println(bookmarkEndList.size());
            String style = graph.getStyle();
            if (("1".equals(style)||"2".equals(style)||"3".equals(style))&& StringUtils.isNotEmpty(text)) {
                list.add(text);
            }
        }
        return list;
    }


    public static void main(String[] args) throws Exception {

//        String path = "/Users/zhangchao/Desktop/CLPS-ALL.docx";
        String path = "/Users/zhangchao/Downloads/test.docx";
//        List<String> list = new ArrayList<String>();
//        if (path.endsWith(".doc")) {
//            list = getWordTitles2003(path);
//        }else if (path.endsWith(".docx")) {
//            list = getWordTitles2007(path);
//        }
//        for (String title : list) {
//            System.out.println(title);
//        }
//        POIFSReader r = new POIFSReader();
//        r.registerListener(new MyPOIFSReaderListener(),
//                "\005SummaryInformation");
//        r.read(new FileInputStream(path));
        readWord(path);

    }
    public static void readWord(String fileName) throws Exception {
        FileInputStream myInput = new FileInputStream(fileName);
        XWPFDocument workbook = new XWPFDocument(myInput);
        List<PackagePart> allEmbedds = workbook.getAllEmbedds();
        for (PackagePart obj : allEmbedds) {
            System.out.println(obj.getPartName());

            obj.getPartName();
//            //the OLE2 Class Name of the object
//            System.out.println("Objects : " + obj.getOLE2ClassName() + "   2 .");
//            String oleName = obj.getOLE2ClassName();
//            if (oleName.equals("Worksheet")) {
//                // some code to process embedded excel file;
//            } else if (oleName.equals("Document")) {
//                System.out.println("Document");
//                DirectoryNode dn = (DirectoryNode) obj.getDirectory();
//                HWPFDocument embeddedWordDocument = new HWPFDocument(dn, fs);
//                System.out.println("Doc : " + embeddedWordDocument.getRange().text());
//                // want to extract document not text into a doc file
//                //************************
//                FileOutputStream fos = new FileOutputStream("E:\\log.txt");
//                fos.write(text.getBytes());
//                //************************
//            } else if (oleName.equals("Presentation")) {
//                // some code to process embedded power point file;
//            } else {
//                // some code to process other kind of embedded files;
//            }
        }
    }
    static class MyPOIFSReaderListener implements POIFSReaderListener
    {
        public void processPOIFSReaderEvent(POIFSReaderEvent event)
        {
            SummaryInformation si = null;
            try
            {
                si = (SummaryInformation)
                        PropertySetFactory.create(event.getStream());
            }
            catch (Exception ex)
            {
                throw new RuntimeException
                        ("Property set stream \"" +
                                event.getPath() + event.getName() + "\": " + ex);
            }
            final String title = si.getTitle();
            if (title != null)
                System.out.println("Title: \"" + title + "\"");
            else
                System.out.println("Document has no title.");
            PropertySet ps = null;
            try
            {
                ps = PropertySetFactory.create(event.getStream());
            }
            catch (NoPropertySetStreamException ex)
            {
                System.out.println("No property set stream: \"" + event.getPath() +
                        event.getName() + "\"");
                return;
            }
            catch (Exception ex)
            {
                throw new RuntimeException
                        ("Property set stream \"" +
                                event.getPath() + event.getName() + "\": " + ex);
            }

            /* Print the name of the property set stream: */
            System.out.println("Property set stream \"" + event.getPath() +
                    event.getName() + "\":");
        }
    }

}
